home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / tcpcmd.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  6KB  |  302 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "timer.h"
  4. #include "mbuf.h"
  5. #include "netuser.h"
  6. #include "internet.h"
  7. #include "tcp.h"
  8. #include "cmdparse.h"
  9.  
  10. /* TCP connection states */
  11. char *tcpstates[] = {
  12.     "Closed",
  13.     "Listen",
  14.     "SYN sent",
  15.     "SYN received",
  16.     "Established",
  17.     "FIN wait 1",
  18.     "FIN wait 2",
  19.     "Close wait",
  20.     "Closing",
  21.     "Last ACK",
  22.     "Time wait"
  23. };
  24.  
  25. /* TCP closing reasons */
  26. char *reasons[] = {
  27.     "Normal",
  28.     "Reset",
  29.     "Timeout",
  30.     "ICMP"
  31. };
  32. /* TCP subcommand table */
  33. int domss(),doirtt(),dortt(),dotcpstat(),dowindow(),dotcpkick(),dotcpreset();
  34. struct cmds tcpcmds[] = {
  35.     "irtt",        doirtt,        0,    NULLCHAR,    NULLCHAR,
  36.     "kick",        dotcpkick,    2,    "tcp kick <tcb>",
  37.         NULLCHAR,
  38.     "mss",        domss,        0,    NULLCHAR,    NULLCHAR,
  39.     "reset",    dotcpreset,    2,    "tcp reset <tcb>",
  40.         NULLCHAR,
  41.     "rtt",        dortt,        3,    "tcp rtt <tcb> <val>",
  42.         NULLCHAR,
  43.     "status",    dotcpstat,    0,    NULLCHAR,    NULLCHAR,
  44.     "window",    dowindow,    0,    NULLCHAR,    NULLCHAR,
  45.     NULLCHAR,    NULLFP,        0,
  46.         "tcp subcommands: irtt kick mss reset rtt status window",
  47.         NULLCHAR,
  48. };
  49. int
  50. dotcp(argc,argv)
  51. int argc;
  52. char *argv[];
  53. {
  54.     return subcmd(tcpcmds,argc,argv);
  55. }
  56.  
  57. /* Eliminate a TCP connection */
  58. /*ARGSUSED*/
  59. static int
  60. dotcpreset(argc,argv)
  61. int argc;
  62. char *argv[];
  63. {
  64.     register struct tcb *tcb;
  65.     extern char notval[];
  66.  
  67.     tcb = (struct tcb *)htol(argv[1]);
  68.     if(!tcpval(tcb)){
  69.         printf(notval);
  70.         return 1;
  71.     }
  72.     close_self(tcb,RESET);
  73.     return 0;
  74. }
  75.  
  76. /* Set initial round trip time for new connections */
  77. static int
  78. doirtt(argc,argv)
  79. int argc;
  80. char *argv[];
  81. {
  82.     long atol();
  83.  
  84.     if(argc < 2)
  85.         printf("%lu\n",tcp_irtt);
  86.     else
  87.         tcp_irtt = atol(argv[1]);
  88.     return 0;
  89. }
  90.  
  91. /* Set smoothed round trip time for specified TCB */
  92. /*ARGSUSED*/
  93. static int
  94. dortt(argc,argv)
  95. int argc;
  96. char *argv[];
  97. {
  98.     register struct tcb *tcb;
  99.     extern char notval[];
  100.     long atol();
  101.  
  102.     tcb = (struct tcb *)htol(argv[1]);
  103.     if(!tcpval(tcb)){
  104.         printf(notval);
  105.         return 1;
  106.     }
  107.     tcb->srtt = atol(argv[2]);
  108.     return 0;
  109. }
  110.  
  111. /* Force a retransmission */
  112. /*ARGSUSED*/
  113. static int
  114. dotcpkick(argc,argv)
  115. int argc;
  116. char *argv[];
  117. {
  118.     register struct tcb *tcb;
  119.     extern char notval[];
  120.  
  121.     tcb = (struct tcb *)htol(argv[1]);
  122.     if(kick_tcp(tcb) == -1){
  123.         printf(notval);
  124.         return 1;
  125.     }
  126.     return 0;
  127. }
  128.  
  129. /* Set default maximum segment size */
  130. static int
  131. domss(argc,argv)
  132. int argc;
  133. char *argv[];
  134. {
  135.     if(argc < 2)
  136.         printf("%u\n",tcp_mss);
  137.     else
  138.         tcp_mss = atoi(argv[1]);
  139.     return 0;
  140. }
  141.  
  142. /* Set default window size */
  143. static int
  144. dowindow(argc,argv)
  145. int argc;
  146. char *argv[];
  147. {
  148.     if(argc < 2)
  149.         printf("%u\n",tcp_window);
  150.     else
  151.         tcp_window = atoi(argv[1]);
  152.     return 0;
  153. }
  154.  
  155. /* Display status of TCBs */
  156. static int
  157. dotcpstat(argc,argv)
  158. int argc;
  159. char *argv[];
  160. {
  161.     register struct tcb *tcb;
  162.     extern char notval[];
  163.  
  164.     if(argc < 2){
  165.         tstat();
  166.     } else {
  167.         tcb = (struct tcb *)htol(argv[1]);
  168.         if(tcpval(tcb))
  169.             state_tcp(tcb);
  170.         else
  171.             printf(notval);
  172.     }
  173.     return 0;
  174. }
  175.  
  176. /* Dump TCP stats and summary of all TCBs
  177. /*     &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State
  178.  *     1234     0     0  xxx.xxx.xxx.xxx:xxxxx  xxx.xxx.xxx.xxx:xxxxx  Established
  179.  */
  180. static int
  181. tstat()
  182. {
  183.     register int i;
  184.     register struct tcb *tcb;
  185.     char *psocket();
  186.  
  187.     printf("conout %u conin %u reset out %u runt %u chksum err %u bdcsts %u\n",
  188.         tcp_stat.conout,tcp_stat.conin,tcp_stat.resets,tcp_stat.runt,
  189.         tcp_stat.checksum,tcp_stat.bdcsts);
  190.     printf("    &TCB Rcv-Q Snd-Q  Local socket           Remote socket          State\n");
  191.     for(i=0;i<NTCB;i++){
  192.         for(tcb=tcbs[i];tcb != NULLTCB;tcb = tcb->next){
  193.             printf("%8lx%6u%6u  ",(long)tcb,tcb->rcvcnt,tcb->sndcnt);
  194.             printf("%-23s",psocket(&tcb->conn.local));
  195.             printf("%-23s",psocket(&tcb->conn.remote));
  196.             printf("%-s",tcpstates[tcb->state]);
  197.             if(tcb->state == LISTEN && (tcb->flags & CLONE))
  198.                 printf(" (S)");
  199.             printf("\n");
  200.         }
  201.     }
  202.     fflush(stdout);
  203.     return 0;
  204. }
  205. /* Dump a TCP control block in detail */
  206. static void
  207. state_tcp(tcb)
  208. struct tcb *tcb;
  209. {
  210.     int32 sent,recvd;
  211.  
  212.     if(tcb == NULLTCB)
  213.         return;
  214.     /* Compute total data sent and received; take out SYN and FIN */
  215.     sent = tcb->snd.una - tcb->iss;    /* Acknowledged data only */
  216.     recvd = tcb->rcv.nxt - tcb->irs;
  217.     switch(tcb->state){
  218.     case LISTEN:
  219.     case SYN_SENT:        /* Nothing received or acked yet */
  220.         sent = recvd = 0;    
  221.         break;
  222.     case SYN_RECEIVED:
  223.         recvd--;    /* Got SYN, no data acked yet */
  224.         sent = 0;
  225.         break;
  226.     case ESTABLISHED:    /* Got and sent SYN */
  227.     case FINWAIT1:        /* FIN not acked yet */
  228.         sent--;
  229.         recvd--;
  230.         break;
  231.     case FINWAIT2:        /* Our SYN and FIN both acked */
  232.         sent -= 2;
  233.         recvd--;
  234.         break;
  235.     case CLOSE_WAIT:    /* Got SYN and FIN, our FIN not yet acked */
  236.     case CLOSING:
  237.     case LAST_ACK:
  238.         sent--;
  239.         recvd -= 2;
  240.         break;
  241.     case TIME_WAIT:        /* Sent and received SYN/FIN, all acked */
  242.         sent -= 2;
  243.         recvd -= 2;
  244.         break;
  245.     }
  246.     printf("Local: %s",psocket(&tcb->conn.local));
  247.     printf(" Remote: %s",psocket(&tcb->conn.remote));
  248.     printf(" State: %s\n",tcpstates[tcb->state]);
  249.     printf("      Init seq    Unack     Next Resent CWind Thrsh  Wind  MSS Queue      Total\n");
  250.     printf("Send:");
  251.     printf("%9lx",tcb->iss);
  252.     printf("%9lx",tcb->snd.una);
  253.     printf("%9lx",tcb->snd.nxt);
  254.     printf("%7lu",tcb->resent);
  255.     printf("%6u",tcb->cwind);
  256.     printf("%6u",tcb->ssthresh);
  257.     printf("%6u",tcb->snd.wnd);
  258.     printf("%5u",tcb->mss);
  259.     printf("%6u",tcb->sndcnt);
  260.     printf("%11lu\n",sent);
  261.  
  262.     printf("Recv:");
  263.     printf("%9lx",tcb->irs);
  264.     printf("         ");
  265.     printf("%9lx",tcb->rcv.nxt);
  266.     printf("%7lu",tcb->rerecv);
  267.     printf("      ");
  268.     printf("      ");
  269.     printf("%6u",tcb->rcv.wnd);
  270.     printf("     ");
  271.     printf("%6u",tcb->rcvcnt);
  272.     printf("%11lu\n",recvd);
  273.  
  274.     if(tcb->reseq != (struct reseq *)NULL){
  275.         register struct reseq *rp;
  276.  
  277.         printf("Reassembly queue:\n");
  278.         for(rp = tcb->reseq;rp != (struct reseq *)NULL; rp = rp->next){
  279.             printf("  seq x%lx %u bytes\n",rp->seg.seq,rp->length);
  280.         }
  281.     }
  282.     if(tcb->backoff > 0)
  283.         printf("Backoff %u ",tcb->backoff);
  284.     if(tcb->flags & RETRAN)
  285.         printf("Retrying ");
  286.     switch(tcb->timer.state){
  287.     case TIMER_STOP:
  288.         printf("Timer stopped ");
  289.         break;
  290.     case TIMER_RUN:
  291.         printf("Timer running (%ld/%ld ms) ",
  292.          (long)MSPTICK * (tcb->timer.start - tcb->timer.count),
  293.          (long)MSPTICK * tcb->timer.start);
  294.         break;
  295.     case TIMER_EXPIRE:
  296.         printf("Timer expired ");
  297.     }
  298.     printf("SRTT %ld ms Mean dev %ld ms\n",tcb->srtt,tcb->mdev);
  299.     fflush(stdout);
  300. }
  301.  
  302.